import React, { Component, PropTypes } from 'react';
import { Popover, Button, Input, Icon, Row, Col, DatePicker } from 'antd'
import 'styles/components/date-range-picker.scss'
import moment from 'moment'
import {messages} from "share/common";
const { WeekPicker, MonthPicker } = DatePicker;
const ButtonGroup = Button.Group;

/**
 * 2019-8-1 Wrote by ZaraNengap:
 * 时间范围选择器
 * 因为antd官方的RangePicker不能单选，所以做了个能单选的
 * 不止如此，也是在项目中首次提出formatter & parser思想的第一个组件
 * 这种思想可能短期人们会觉得麻烦，长期来看绝对是一把代码优化的利器
 */
class DateRangePicker extends Component {

  constructor(props) {
    super(props);
    const value = props.value;
    this.state = {
      startDate: props.parser(value)[0],
      endDate: props.parser(value)[1],
      visible: false
    };
  }

  input = null;

  componentMap = {
    WeekPicker,
    MonthPicker
  };

  static formatDate = (format, date) => date ? date.format(format) : '';

  static getInputValue = (startDate, endDate, format) => {
    if(!startDate && !endDate)
      return null;
    else
      return `${DateRangePicker.formatDate(format, startDate)} ~ ${DateRangePicker.formatDate(format, endDate)}`
  };

  componentWillReceiveProps(nextProps) {
    if('value' in nextProps) {
      const { value, parser } = nextProps;
      if(value)
        this.setState({
          startDate: parser(value)[0],
          endDate: parser(value)[1]
        });
      else
        this.setState({
          startDate: null,
          endDate: null
        })
    }
  }

  onChange = () => {
    const { onChange, formatter } = this.props;
    const { startDate, endDate } = this.state;
    onChange && onChange(formatter(startDate, endDate));
  };

  handleChangeDate = (value, key) => {
    this.setState({ [key]: value }, this.onChange);
  };

  getFormatMoment = value => {
    const { format } = this.props;
    return value ? moment(value.format(format)) : null;
  };

  disabledDate = (currentDate, key) => {
    const { disabledDate } = this.props;
    const { startDate, endDate } = this.state;
    let propsTest = disabledDate(currentDate);
    let nowMoment = this.getFormatMoment(currentDate);
    if(key === 'startDate') {
      let anotherMoment = this.getFormatMoment(endDate);
      return propsTest || (endDate && anotherMoment.isBefore(nowMoment))
    } else {
      let anotherMoment = this.getFormatMoment(startDate);
      return propsTest || (startDate && anotherMoment.isAfter(nowMoment))
    }
  };

  renderDateRangePickerPopover = () => {
    const { format, component, radios } = this.props;
    let Component = this.componentMap[component] || DatePicker;
    return (
      <div className='date-range-picker-popover-content'>
        {[{
          text: messages('common.start.date')/*起始日期*/,
          key: 'startDate'
        }, {
          text: messages('common.end.date')/*结束日期*/,
          key: 'endDate'
        }].map(item => (
          <Row key={item.key} className='date-range-picker-popover-content-date'>
            <Col span={7}>
              {item.text}
            </Col>
            <Col span={16} offset={1}>
              <Component
                disabledDate={currentDate => this.disabledDate(currentDate, item.key)}
                classname='date0range-picker-popover-date-picker'
                format={format}
                getCalendarContainer={trigger => trigger.parentNode}
                value={this.state[item.key]}
                onChange={value => this.handleChangeDate(value, item.key)}
              />
            </Col>
          </Row>
        ))}
        {radios && radios.length > 0 && (
          <div>
            <Row className='date-range-picker-popover-content-radio'>
              <Col span={7}>
                {messages('components.key1060')/*快速选择*/}
              </Col>
              <Col span={16} offset={1}>
                <ButtonGroup onChange={this.handleChangeRadio}>
                  {radios.map((radio, i) => <Button key={i} onClick={() => this.handleChangeRange(i)}>{radio.text}</Button>)}
                </ButtonGroup>
              </Col>
            </Row>
          </div>
        )}
      </div>
    )
  };

  handleChangeRange = i => {
    const { radios } = this.props;
    this.setState({
      startDate: radios[i].startDate,
      endDate: radios[i].endDate
    }, this.onChange)
  };

  onClickInput = () => {
    const { disabled } = this.props;
    //取消焦点
    if(!disabled) {
      this.setState({ visible: true });
      this.input.blur();
    }
  };

  clear = e => {
    e.stopPropagation();
    this.setState({
      startDate: null,
      endDate: null
    }, this.onChange)
  };

  render() {
    const {
      placeholder, size, disabled, allowClear,
      format, style, className = '', getPopupContainer
    } = this.props;
    const { visible, startDate, endDate } = this.state;
    const inputProps = { placeholder, size, disabled };
    const inputValue = DateRangePicker.getInputValue(startDate, endDate, format);
    const inputWrap = (
      <div className={`date-range-picker ${className}`} style={style}>
        {allowClear && !disabled && inputValue && <Icon
          className={`ant-select-selection__clear ${size}`}
          type="close-circle"
          onClick={this.clear}
        />}
        <Input
          ref={input => this.input = input}
          {...inputProps}
          onClick={this.onClickInput}
          value={inputValue}
          disabled={disabled}
          className='date-range-picker-input'
          suffix={<Icon type="calendar" className='font-disabled' />}
        />
      </div>
    );
    return disabled ? inputWrap : (
      <Popover
        trigger='click'
        content={this.renderDateRangePickerPopover()}
        placement='bottomLeft'
        visible={visible}
        overlayClassName='date-range-picker-popover'
        onVisibleChange={visible => this.setState({ visible })}
        getPopupContainer={getPopupContainer}
      >
        {inputWrap}
      </Popover>
    );
  }

  static propTypes = {
    placeholder: PropTypes.string,
    size: PropTypes.string,
    allowClear: PropTypes.bool,
    disabled: PropTypes.bool,
    value: PropTypes.any,
    format: PropTypes.string,
    component: PropTypes.any,
    formatter: PropTypes.func,  //传出数据时可根据次函数规定onChange返回的数据结构
    parser: PropTypes.func,  //formatter的记过当作传入数据时的结构重构，必须返回一个数组，第0位赋值给startDate，第1位赋值给endDate
    disabledDate: PropTypes.func,
    radios: PropTypes.array,
    style: PropTypes.object,
    className: PropTypes.string,
    getPopupContainer: PropTypes.func
  };

  static defaultProps = {
    size: 'default',
    format: 'YYYY-MM-DD',
    placeholder: messages('common.select')/*"请选择"*/,
    component: DatePicker,
    formatter: (startDate, endDate) => startDate || endDate ? [startDate, endDate] : [],
    parser: value => (value instanceof Array) ? value : [],
    allowClear: true,
    disabledDate: () => false,
    radios: [{
      text: messages('components.key1052')/*6个月*/,
      startDate: moment().subtract(6, 'month'),
      endDate: moment()
    }, {
      text: messages('components.key1053')/*3个月*/,
      startDate: moment().subtract(3, 'month'),
      endDate: moment()
    }, {
      text: messages('components.key1054')/*本月*/,
      startDate: moment(moment().format('YYYY-MM-01')),
      endDate: moment()
    }],
    getPopupContainer: triggerNode => triggerNode.parentNode
  }

}

export default DateRangePicker;
